﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SimpleMapper
{
    /// <summary>
    /// 类型扩展方法
    /// </summary>
    internal static class TypeExtensions
    {
        /// <summary>
        /// 基本数据类型完全名称集合
        /// </summary>
        private static readonly HashSet<string> _basicDataTypeFullNameHashSet = new HashSet<string>
        {
            "System.String",
            "System.Boolean",
            "System.Char",
            "System.SByte",
            "System.Byte",
            "System.Int16",
            "System.UInt16",
            "System.Int32",
            "System.UInt32",
            "System.Int64",
            "System.UInt64",
            "System.Single",
            "System.Double",
            "System.Decimal",
            "System.DateTime",
        };

        /// <summary>
        /// 可转换数据类型
        /// <para>
        /// 基本数据类型、枚举、可为空基本数据值类型
        /// </para>
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static bool IsConvertibleType(this Type type)
        {
            // 是否枚举类型
            if (type.IsEnum) return true;
            // 是否基本数据类型
            if (type.IsBasicType()) return true;
            // 是否可为空基本数据值类型
            if (type.IsNullableBasicValueType()) return true;
            // 其它都不是基本类型
            return false;
        }
        /// <summary>
        /// 是否基本数据类型
        /// <para>
        /// <see cref="string"/>
        /// <see cref="bool"/>
        /// <see cref="char"/>
        /// <see cref="sbyte"/>
        /// <see cref="byte"/>
        /// <see cref="short"/>
        /// <see cref="ushort"/>
        /// <see cref="int"/>
        /// <see cref="uint"/>
        /// <see cref="long"/>
        /// <see cref="ulong"/>
        /// <see cref="float"/>
        /// <see cref="double"/>
        /// <see cref="decimal"/>
        /// <see cref="DateTime"/>
        /// </para>
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static bool IsBasicType(this Type type)
        {
            return _basicDataTypeFullNameHashSet.Contains(type.FullName);
        }

        /// <summary>
        /// 是否可为空基本值类型
        /// <see cref="Nullable{T}"/>
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static bool IsNullableBasicValueType(this Type type)
        {
            if (type.IsValueType && type.IsGenericType)
            {
                // 取可为空值类型的基础类型
                var underlyingType = Nullable.GetUnderlyingType(type);
                // 检查基础类型是否为基本类型
                return underlyingType.IsBasicType();
            }
            return false;
        }

        /// <summary>
        /// 是否字符串引用类型
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static bool IsStringType(this Type type)
        {
            return type == typeof(string);
        }
        /// <summary>
        /// 是否数字值类型
        /// <see cref="decimal"/>
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static bool IsDecimalType(this Type type)
        {
            return type == typeof(decimal);
        }
        /// <summary>
        /// 是否日期时间类型
        /// <see cref="DateTime"/>
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static bool IsDateTimeType(this Type type)
        {
            return type == typeof(DateTime);
        }

        /// <summary>
        /// 是否基本类型
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        //public static bool IsBasicType(this Type type)
        //{
        //    // 枚举值类型
        //    if (type.IsEnum) return true;
        //    // 基元值类型 Boolean, Char, SByte, Byte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double
        //    if (type.IsPrimitive) return true;
        //    // 字符串类型
        //    if (type.IsStringType()) return true;
        //    // 数字值类型
        //    if (type.IsDecimalType()) return true;
        //    // 日期时间值类型 DateTime
        //    if (type.IsDateTimeType()) return true;
        //    // 可为空基本值类型
        //    if (type.IsNullableBasicValueType()) return true;
        //    // 其它值与引用类型都为false
        //    return false;
        //}
    }
}
